home *** CD-ROM | disk | FTP | other *** search
/ HamCall (October 1991) / HamCall (Whitehall Publishing)(1991).bin / prgming / ctutor / chap08.txt < prev    next >
Text File  |  1990-10-14  |  19KB  |  410 lines

  1.  
  2.                                                      Chapter 8
  3.  
  4.                                                       POINTERS
  5.  
  6.  
  7.  
  8. WHAT IS A POINTER?
  9. ______________________________________________________________
  10.  
  11. Simply stated, a pointer is an address.          =============
  12. Instead of being a variable, it is a pointer       POINTER.C
  13. to a variable stored somewhere in the address    =============
  14. space of the program.  It is always best to
  15. use an example so load the file named POINTER.C and display
  16. it on your monitor for an example of a program with some
  17. pointers in it.
  18.  
  19. For the moment, ignore the data declaration statement where
  20. we define "index" and two other fields beginning with a star.
  21. It is properly called an asterisk, but for reasons we will see
  22. later, let's agree to call it a star.  If you observe the
  23. first statement, it should be clear that we assign the value
  24. of 39 to the variable "index".  This is no surprise, we have
  25. been doing it for several programs now.  The next statement
  26. however, says to assign to "pt1" a strange looking value,
  27. namely the variable "index" with an ampersand in front of it.
  28. In this example, pt1 and pt2 are pointers, and the variable
  29. "index" is a simple variable.  Now we have a problem.  We need
  30. to learn how to use pointers in a program, but to do so
  31. requires that first we define the means of using the pointers
  32. in the program.
  33.  
  34. The following two rules will be somewhat confusing to you at
  35. first but we need to state the definitions before we can use
  36. them.  Take your time, and the whole thing will clear up very
  37. quickly.
  38.  
  39.  
  40. TWO VERY IMPORTANT RULES
  41. ______________________________________________________________
  42.  
  43. The following two rules are very important when using pointers
  44. and must be thoroughly understood.
  45.  
  46. 1.   A variable name with an ampersand in front of it defines
  47.      the address of the variable and therefore points to the
  48.      variable.  You can therefore read line seven as "pt1 is
  49.      assigned the value of the address of index".
  50.  
  51. 2.   A pointer with a "star" in front of it refers to the
  52.      value of the variable pointed to by the pointer.  Line
  53.      ten of the program can be read as "The stored (starred)
  54.      value to which the pointer "pt1" points is assigned the
  55.      value 13".  Now you can see why it is convenient to think
  56.      of the asterisk as a star,  it sort of sounds like the
  57.      word store.
  58.  
  59.                                                            8-1
  60.  
  61.                                           Chapter 8 - Pointers
  62.  
  63. MEMORY AIDS
  64. ______________________________________________________________
  65.  
  66. 1.   Think of & as an address.
  67. 2.   Think of * as a star referring to stored.
  68.  
  69. Assume for the moment that "pt1" and "pt2" are pointers (we
  70. will see how to define them shortly).  As pointers, they do
  71. not contain a variable value but an address of a variable and
  72. can be used to point to a variable.  Figure 8-1 is a graphical
  73. representation of the data space as it is configured at this
  74. time.  A box represents a variable, and a box with a dot in
  75. it represents a pointer.  At this time the pointers are not
  76. pointing at anything, so they have no arrows emanating from
  77. the boxes.
  78.  
  79. Continuing execution of the program, we come to line 7 which
  80. assigns the pointer "pt1" to point to the variable we have
  81. already defined as "index" because we have assigned the
  82. address of "index" to "pt1".  Since we have a pointer to
  83. "index", we can manipulate the value of "index" by using
  84. either the variable name itself, or the pointer.  Figure 8-2
  85. depicts the condition of the data space after executing line
  86. seven.
  87.  
  88. Line 10 modifies the value by using the pointer. Since the
  89. pointer "pt1" points to the variable "index", then putting a
  90. star in front of the pointer name refers to the memory
  91. location to which it is pointing.  Line 10 therefore assigns
  92. to "index" the value of 13.  Anyplace in the program where it
  93. is permissible to use the variable name "index", it is also
  94. permissible to use the name "*pt1" since they are identical
  95. in meaning until the pointer is reassigned to some other
  96. variable.
  97.  
  98.  
  99. ANOTHER POINTER
  100. ______________________________________________________________
  101.  
  102. Just to add a little intrigue to the system, we have another
  103. pointer defined in this program, "pt2".   Since "pt2" has not
  104. been assigned a value prior to statement 8, it doesn't point
  105. to anything, it contains garbage.  Of course, that is also
  106. true of any variable until a value is assigned to it.  The
  107. statement in line 8 assigns "pt2" the same address as "pt1",
  108. so that now "pt2" also points to the variable "index".  So to
  109. continue the definition from the last paragraph, anyplace in
  110. the program where it is permissible to use the variable
  111. "index", it is also permissible to use the name "*pt2" because
  112. they  are identical in meaning.  This fact is illustrated in
  113. the first "printf" statement since this statement uses the
  114. three means of identifying the same variable to print out the
  115. same variable three times.  Refer to figure 8-3 for the
  116. representation of the data space.
  117.  
  118.                                                            8-2
  119.  
  120.                                           Chapter 8 - Pointers
  121.  
  122. THERE IS ONLY ONE VARIABLE
  123. ______________________________________________________________
  124.  
  125. Note carefully that, even though it appears that there are
  126. three variables, there is really only one variable.  The two
  127. pointers point to the single variable.  This is illustrated
  128. in the next statement which assigns the value of 13 to the
  129. variable "index", because that is where the pointer "pt1" is
  130. pointing.  The next "printf" statement causes the new value
  131. of 13 to be printed out three times.  Keep in mind that there
  132. is really only one variable to be changed, not three.  Figure
  133. 8-4 is the graphical representation of the data space at this
  134. point.
  135.  
  136. This is admittedly a very difficult concept, but since it is
  137. used extensively in all but the most trivial C programs, it
  138. is well worth your time to stay with this material until you
  139. understand it thoroughly.
  140.  
  141.  
  142. HOW DO YOU DECLARE A POINTER?
  143. ______________________________________________________________
  144.  
  145. Now to keep a promise and tell you how to declare a pointer.
  146. Refer to the third line of the program and you will see our
  147. old familiar way of defining the variable "index", followed
  148. by two more definitions.  The second definition can be read
  149. as "the storage location to which "pt1" points will be an int
  150. type variable".  Therefore, "pt1" is a pointer to an int type
  151. variable.  Likewise, "pt2" is another pointer to an int type
  152. variable.
  153.  
  154. A pointer must be defined to point to some type of variable.
  155. Following a proper definition, it cannot be used to point to
  156. any other type of variable or it will result in a "type
  157. incompatibility" error.  In the same manner that a "float"
  158. type of variable cannot be added to an "int" type variable,
  159. a pointer to a "float" variable cannot be used to point to an
  160. integer variable.  Compile and run this program and observe
  161. that there is only one variable and the single statement in
  162. line 10 changes the one variable which is displayed three
  163. times.
  164.  
  165.  
  166. THE SECOND PROGRAM WITH POINTERS
  167. ______________________________________________________________
  168.  
  169. In these few pages so far on pointers, we       ==============
  170. have covered a lot of territory, but it is        POINTER2.C
  171. important territory.  We still have a lot of    ==============
  172. material to cover so stay in tune as we
  173. continue this important aspect of C.  Load the next file named
  174. POINTER2.C and display it on your monitor so we can continue
  175. our study.
  176.  
  177.                                                            8-3
  178.  
  179.                                           Chapter 8 - Pointers
  180.  
  181. In this program we have defined several variables and two
  182. pointers.  The first pointer named "there" is a pointer to a
  183. "char" type variable and the second named "pt" points to an
  184. "int" type variable.  Notice also that we have defined two
  185. array variables named "strg" and "list".  We will use them to
  186. show the correspondence between pointers and array names.
  187.  
  188. Figure 8-5 depicts the data space at this time.  There are
  189. three variables, two pointers, and two strings.  Each string
  190. is composed of the string itself and a pointer which points
  191. to the beginning of the string.  This will be completely
  192. defined in the next paragraph.  The string itself is composed
  193. of a number of identical elements of which only a few at the
  194. beginning and a few at the end are depicted graphically.
  195.  
  196.  
  197. A STRING VARIABLE IS ACTUALLY A POINTER
  198. ______________________________________________________________
  199.  
  200. In the programming language C, a string variable is defined
  201. to be simply a pointer to the beginning of a string.  This
  202. will take some explaining.  Refer to the example program on
  203. your monitor.  You will notice that first we assign a string
  204. constant to the string variable named "strg" so we will have
  205. some data to work with.  Next, we assign the value of the
  206. first element to the variable "one", a simple "char" variable.
  207. Next, since the string name is a pointer by definition of the
  208. C language, we can assign the same value to "two" by using the
  209. star and the string name.  The result of the two assignments
  210. are such that "one" now has the same value as "two", and both
  211. contain the character "T", the first character in the string.
  212. Note that it would be incorrect to write line 10 as "two =
  213. *strg[0];" because the star takes the place of the square
  214. brackets.
  215.  
  216. For all practical purposes, "strg" is a pointer.  It does,
  217. however, have one restriction that a true pointer does not
  218. have.  It cannot be changed like a variable, but must always
  219. contain the initial value and therefore always points to its
  220. string.  It could be thought of as a pointer constant, and in
  221. some applications you may desire a pointer that cannot be
  222. corrupted in any way.  Even though it cannot be changed, it
  223. can be used to refer to other values than the one it is
  224. defined to point to, as we will see in the next section of the
  225. program.
  226.  
  227. Moving ahead to line 13, the variable "one" is assigned the
  228. value of the ninth variable (since the indexing starts at
  229. zero) and "two" is assigned the same value because we are
  230. allowed to index a pointer to get to values farther ahead in
  231. the string.  Both variables now contain the character "a".
  232.  
  233.  
  234.                                                            8-4
  235.  
  236.                                           Chapter 8 - Pointers
  237.  
  238. POINTER INDEXING
  239. ______________________________________________________________
  240.  
  241. The C programming language takes care of indexing for us
  242. automatically by adjusting the indexing for the type of
  243. variable the pointer is pointing to.  In this case, the index
  244. of 8 is simply added to the pointer value before looking up
  245. the desired result because a "char" type variable is one byte
  246. long.  If we were using a pointer to an "int" type variable,
  247. the index would be doubled and added to the pointer before
  248. looking up the value because an "int" type variable uses two
  249. bytes per value stored.  When we get to the chapter on
  250. structures, we will see that a variable can have many, even
  251. into the hundreds or thousands, of bytes per variable, but the
  252. indexing will be handled automatically for us by the system.
  253.  
  254. The data space is now in the condition defined graphically in
  255. figure 8-6.  The string named strg has been filled and the two
  256. variables named one and two have the letter "a" stored in
  257. them.  Since "there" is already a pointer, it can be assigned
  258. the address of the eleventh element of "strg" by the statement
  259. in line 17 of the program.  Remember that since "there" is a
  260. true pointer, it can be assigned any value as long as that
  261. value represents a "char" type of address.  It should be clear
  262. that the pointers must be "typed" in order to allow the
  263. pointer arithmetic described in the last paragraph to be done
  264. properly.  The third and fourth outputs will be the same,
  265. namely the letter "c".
  266.  
  267.  
  268. POINTER ARITHMETIC
  269. ______________________________________________________________
  270.  
  271. Not all forms of arithmetic are permissible on a pointer.
  272. Only those things that make sense, considering that a pointer
  273. is an address somewhere in the computer.  It would make sense
  274. to add a constant to an address, thereby moving it ahead in
  275. memory that number of places.  Likewise, subtraction is
  276. permissible, moving it back some number of locations.  Adding
  277. two pointers together would not make sense because absolute
  278. memory addresses are not additive.  Pointer multiplication is
  279. also not allowed, as that would be a funny number.  If you
  280. think about what you are actually doing, it will make sense
  281. to you what is allowed, and what is not.
  282.  
  283.  
  284. NOW FOR AN INTEGER POINTER
  285. ______________________________________________________________
  286.  
  287. The array named "list" is assigned a series of values from 100
  288. to 199 in order to have some data to work with.  Next we
  289. assign the pointer "pt" the address of the 28th element of the
  290. list and print out the same value both ways to illustrate that
  291. the system truly will adjust the index for the "int" type
  292.  
  293.                                                            8-5
  294.  
  295.                                           Chapter 8 - Pointers
  296.  
  297. variable.  You should spend some time in this program until
  298. you feel you fairly well understand these lessons on pointers.
  299.  
  300. Compile and execute POINTER2.C and study the output.  At the
  301. termination execution, the data space will be as depicted in
  302. figure 8-7.
  303.  
  304.  
  305. FUNCTION DATA RETURN WITH A POINTER
  306. ______________________________________________________________
  307.  
  308. You may recall that back in the lesson on       ==============
  309. functions we mentioned that there were two         TWOWAY.C
  310. ways to get variable data back from a           ==============
  311. function.  One way is through use of the
  312. array, and you should be right on the verge of guessing the
  313. other way.  If your guess is through use of a pointer, you are
  314. correct.  Load and display the program named TWOWAY.C for an
  315. example of this.
  316.  
  317. In TWOWAY.C, there are two variables defined in the main
  318. program "pecans" and "apples".  Notice that neither of these
  319. is defined as a pointer.  We assign values to both of these
  320. and print them out, then call the function "fixup" taking with
  321. us both of these values.  The variable "pecans" is simply sent
  322. to the function, but the address of the variable "apples" is
  323. sent to the function.  Now we have a problem.  The two
  324. arguments are not the same, the second is a pointer to a
  325. variable.  We must somehow alert the function to the fact that
  326. it is supposed to receive an integer variable and a pointer
  327. to an integer variable.  This turns out to be very simple.
  328. Notice that the parameter definitions in the function define
  329. "nuts" as an integer, and "fruit" as a pointer to an integer.
  330. The call in the main program therefore is now in agreement
  331. with the function heading and the program interface will work
  332. just fine.
  333.  
  334. In the body of the function, we print the two values sent to
  335. the function, then modify them and print the new values out.
  336. This should be perfectly clear to you by now.  The surprise
  337. occurs when we return to the main program and print out the
  338. two values again.  We will find that the value of pecans will
  339. be restored to its value before the function call because the
  340. C language makes a copy of the item in question and takes the
  341. copy to the called function, leaving the original intact.  In
  342. the case of the variable "apples", we made a copy of a pointer
  343. to the variable and took the copy of the pointer to the
  344. function.  Since we had a pointer to the original variable,
  345. even though the pointer was a copy, we had access to the
  346. original variable and could change it in the function.  When
  347. we returned to the main program, we found a changed value in
  348. "apples" when we printed it out.
  349.  
  350.  
  351.                                                            8-6
  352.  
  353.                                           Chapter 8 - Pointers
  354.  
  355. This is illustrated graphically in figure 8-8.  The state of
  356. the system is illustrated following execution of line 22 of
  357. the program.
  358.  
  359. By using a pointer in a function call, we can have access to
  360. the data in the function and change it in such a way that when
  361. we return to the calling program, we have a changed value of
  362. data.   It must be pointed out however, that if you modify the
  363. value of the pointer itself in the function, you will have a
  364. restored pointer when you return because the pointer you use
  365. in the function is a copy of the original.  In this example,
  366. there was no pointer in the main program because we simply
  367. sent the address to the function, but in many programs you
  368. will use pointers in function calls.  One of the places you
  369. will find need for pointers in function calls will be when you
  370. request data input using standard input/output routines.
  371. These will be covered in the next two chapters.  Compile and
  372. run TWOWAY.C and observe the output.
  373.  
  374.  
  375. POINTERS ARE VALUABLE
  376. ______________________________________________________________
  377.  
  378. Even though you are probably somewhat intimidated at this
  379. point by the use of pointers, you will find that after you
  380. gain experience, you will use them profusely in many ways.
  381. You will also use pointers in every program you write other
  382. than the most trivial because they are so useful.  You should
  383. probably go over this material carefully several times until
  384. you feel comfortable with it because it is very important in
  385. the area of input/output which is next on the agenda.
  386.  
  387.  
  388. PROGRAMMING EXERCISES
  389. ______________________________________________________________
  390.  
  391. 1.   Define a character array  and use "strcpy" to copy a
  392.      string into it. Print the string out by using a loop with
  393.      a pointer to print out one character at a time.
  394.      Initialize the pointer to the first element and use the
  395.      double plus sign to increment the pointer. Use a separate
  396.      integer variable to count the characters to print.
  397.  
  398. 2.   Modify the program to print out the string backwards by
  399.      pointing to the end and using a decrementing pointer.
  400.  
  401.  
  402.  
  403. Note; The figures referred to in this chapter are graphics
  404.       which are impossible to include in a text file.  Since
  405.       there is no way to include them, we have made it possi-
  406.       ble for you to obtain a copy of these figures.  See the
  407.       READ.ME file for details.
  408.                                                            8-7
  409.  
  410.